﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.DB.Plumbing;
using YArchitech.Revit;

namespace YArchitech.Temp
{
	internal static class YJKElementNodeExtern
	{
		public static bool GetSideConnector(this ElementNode en, out Connector side1, out Connector side2)
		{
			side1 = null;
			side2 = null;
			if (en.SubConnectors == null)
			{
				return false;
			}
			IEnumerable<Connector> enumerable = from conn in en.SubConnectors
			orderby conn.Flow descending
			select conn;
			int num = 0;
			IEnumerator<Connector> enumerator = enumerable.GetEnumerator();
			while (enumerator.MoveNext() && num < 3)
			{
				num++;
				if (1 == num)
				{
					side1 = enumerator.Current;
				}
				else if (2 == num)
				{
					side2 = enumerator.Current;
				}
			}
			return true;
		}

		public static void DumpIntoXML(this ElementNode en, XElement xeParent)
		{
			FamilyInstance familyInstance = en.Element as FamilyInstance;
			XElement xelement = new XElement("MEPObject");
			xeParent.Add(xelement);
			xelement.SetAttributeValue("Id", en.Element.Id.IntegerValue);
			xelement.SetAttributeValue("Name", en.Element.Name);
			if (familyInstance != null)
			{
				MEPModel mepmodel = familyInstance.MEPModel;
				string value = string.Empty;
				if (mepmodel is MechanicalEquipment)
				{
					value = "MechanicalEquipment";
					xelement.SetAttributeValue("Type", value);
				}
				else if (mepmodel is MechanicalFitting)
				{
					MechanicalFitting mechanicalFitting = mepmodel as MechanicalFitting;
					value = "MechanicalFitting";
					xelement.SetAttributeValue("Type", value);
					xelement.SetAttributeValue("Category", en.Element.Category.Name);
					xelement.SetAttributeValue("PartType", mechanicalFitting.PartType.ToString());
				}
				else
				{
					value = "FamilyInstance";
					xelement.SetAttributeValue("Type", value);
					xelement.SetAttributeValue("Category", en.Element.Category.Name);
				}
			}
			else
			{
				string name = en.Element.GetType().Name;
				xelement.SetAttributeValue("Type", name);
				xelement.SetAttributeValue("Flow", RevitUtils.GetFlow(en.Element, BuiltInParameter.RBS_PIPE_FLOW_PARAM));
			}
			if (en.Next == null)
			{
				xelement.SetAttributeValue("Next", "NULL");
			}
			else
			{
				en.Next.DumpIntoXML(xeParent);
			}
			if (en.SubElementNode == null)
			{
				return;
			}
			foreach (ElementNode en2 in en.SubElementNode)
			{
				XElement xelement2 = new XElement("Path");
				xelement.Add(xelement2);
				en2.DumpIntoXML(xelement2);
			}
		}

		public static HYMEPObject CreateObject(this ElementNode en, ref HYPipeSystem system)
		{
			if (en.Element == null)
			{
				return null;
			}
			HYMEPObject hymepobject = en.CreateObject();
			if (hymepobject == null)
			{
				return null;
			}
			system.Add(hymepobject);
			ElementNode next = en.Next;
			if (next != null)
			{
				hymepobject.AddNext(next, ref system);
			}
			if (hymepobject is HYAccessory)
			{
				if (en.SubElementNode != null)
				{
					hymepobject.AddNext(en.SubElementNode.First<ElementNode>(), ref system);
				}
			}
			else if (en.SubElementNode != null)
			{
				foreach (ElementNode ndSub in en.SubElementNode)
				{
					en.AddSubObject(hymepobject, ndSub, ref system);
				}
			}
			return hymepobject;
		}

		private static void AddNext(this HYMEPObject objThis, ElementNode enNext, ref HYPipeSystem system)
		{
			HYMEPObject hymepobject = enNext.CreateObject(ref system);
			if (hymepobject != null)
			{
				objThis.SetNext(hymepobject);
				objThis.Flow = hymepobject.Flow + hymepobject.AddFlow;
			}
		}

		public static HYMEPObject CreateObject(this ElementNode en)
		{
			Element element = en.Element;
			if (DbUtils.IsPipe(element))
			{
				return RevitDataExchange.CreateStraight(element as Pipe);
			}
			if (DbUtils.IsFlexPipe(element))
			{
				return RevitDataExchange.CreateStraight(element as FlexPipe);
			}
			FamilyInstance fi = element as FamilyInstance;
			if (DbUtils.IsPipeFitting(element))
			{
				Connector connSub = null;
				Connector connSub2 = null;
				en.GetSideConnector(out connSub, out connSub2);
				return RevitDataExchange.CreateFitting(fi, en.ConnectorIn, en.ConnectorOut, connSub, connSub2);
			}
			if (DbUtils.IsPipeAccessory(element))
			{
				return RevitDataExchange.CreateAccessory(fi, en.ConnectorIn);
			}
			if (DbUtils.IsMechanicalEquipment(element))
			{
				return RevitDataExchange.CreateTerminal(fi, en.ConnectorIn);
			}
			return null;
		}

		public static void AddSubObject(this ElementNode enThis, HYMEPObject objThis, ElementNode ndSub, ref HYPipeSystem system)
		{
			if (ndSub == null)
			{
				return;
			}
			HYMEPObject hymepobject = ndSub.CreateObject(ref system);
			if (hymepobject == null)
			{
				return;
			}
			objThis.Flow += hymepobject.Flow;
			objThis.Flow += objThis.AddFlow;
			if (objThis is HYPipeStraight)
			{
				objThis.SetNext(hymepobject);
				return;
			}
			if (objThis is HYPipeTee)
			{
				HYPipeTee hypipeTee = objThis as HYPipeTee;
				Connector connector = null;
				Connector connector2 = null;
				enThis.GetSideConnector(out connector, out connector2);
				if (RevitUtils.IsLink(connector, ndSub.ConnectorIn))
				{
					hypipeTee.SetSideObject(hymepobject);
					hypipeTee.SideCofficient = connector.Coefficient;
				}
				if (objThis is HYPipeCross)
				{
					HYPipeCross hypipeCross = objThis as HYPipeCross;
					if (RevitUtils.IsLink(connector2, ndSub.ConnectorIn))
					{
						hypipeCross.SetSide2Object(hymepobject);
						hypipeCross.Side2Cofficient = connector2.Coefficient;
					}
				}
			}
		}
	}
}
